home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
mtex
/
show.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
23KB
|
781 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#include <gl/gl.h>
#include <gl/device.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "colors.h"
#include "image.h"
#include "types.h"
#include "other.h"
#define USE_NORMAL 1
#define USE_COLOR 2
#define USE_TEXTURE 4
#define X 0
#define Y 1
#define Z 2
#define U 0
#define V 1
#define PI 3.1415926535897
#define SET2( A, B, C ) {(A)[0]=(B);(A)[1]=(C);}
#define SETXYZ( A, B, C, D ) {(A)[X]=(B);(A)[Y]=(C);(A)[Z]=(D);}
#define AVG2F( A, B ) (((A)+(B))/2.0)
#define AVG3F( A, B, C ) (((A)+(B)+(C))/3.0)
#define AVG4F( A, B, C, D ) (((A)+(B)+(C)+(D))/4.0)
#define AVG2FXYZ( A, B, C ) {(A)[X]=AVG2F((B)[X],(C)[X]);(A)[Y]=AVG2F((B)[Y],(C)[Y]);(A)[Z]=AVG2F((B)[Z],(C)[Z]);}
#define COPY( A, B) {(A)[X]=(B)[X];(A)[Y]=(B)[Y];(A)[Z]=(B)[Z];}
#define COPYVXYZ( A, B, C, D) {COPY((A).v1.xyz,(B));COPY((A).v2.xyz,(C));COPY((A).v3.xyz,(D));}
#define COPY3V( A, B ) {COPY((A).v1,(B).v1);COPY((A).v2,(B).v2);COPY((A).v3,(B).v3);}
#define COPY3N( A, B ) {COPY((A).v1,(B.v1));COPY((A).v2,(B).v2);COPY((A).v3,(B).v3);}
#define FLIP( A ) {(A)[X]=-(A)[X];(A)[Y]=-(A)[Y];(A)[Z]=-(A)[Z];}
#define DISTANCE( A, B ) \
sqrtf(((A)[X]-(B)[X])*((A)[X]-(B)[X])+\
((A)[Y]-(B)[Y])*((A)[Y]-(B)[Y])+\
((A)[Z]-(B)[Z])*((A)[Z]-(B)[Z]))
#define XYZ_LEN( A ) sqrtf((A)[X]*(A)[X]+(A)[Y]*(A)[Y]+(A)[Z]*(A)[Z])
#define NORMALIZE( A, L ) {L=XYZ_LEN(A); if (L>0.0){(A)[X]/=L;(A)[Y]/=L;(A)[Z]/=L;}}
#define CROSS3D( A, B, C ) { \
(A)[X] = (B)[Y] * (C)[Z] - (B)[Z] * (C)[Y]; \
(A)[Y] = -(B)[X] * (C)[Z] + (B)[Z] * (C)[X]; \
(A)[Z] = (B)[X] * (C)[Y] - (B)[Y] * (C)[X]; \
}
#define SUBXYZ( A, B, C ) { \
(A)[X] = (B)[X] - (C)[X]; \
(A)[Y] = (B)[Y] - (C)[Y]; \
(A)[Z] = (B)[Z] - (C)[Z]; \
}
#define DIVXYZ( A, B ) { \
(A)[X] /= (B); \
(A)[Y] /= (B); \
(A)[Z] /= (B); \
}
typedef float point_t[3];
typedef float tri_tex_t[6];
typedef struct {
point_t xyz;
point_t n;
float t[2];
long abgr;
} p9_t;
typedef struct {
p9_t v1;
p9_t v2;
p9_t v3;
} tri_t;
typedef float mat3x3_t[3][3];
long primes[156] =
{8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713,
8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821,
8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941,
8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, 9043, 9049,
9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181,
9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293,
9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413,
9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497,
9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631,
9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749,
9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857,
9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973};
Matrix identity = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
long show_indexes[6];
Boolean texmap_random;
Boolean texture_loaded = FALSE;
long map_rotation,tex_prop_select;
long maximum_z;
long texture_components_per_pixel,texture_width,texture_height;
long seed;
float my_noise;
unsigned long *texture_image_in_mem;
p9_t xa = {1.0, 0.0, 0.0};
p9_t za = {0.0, 0.0, 1.0};
p9_t org = {0.0, 0.0, 0.0};
p9_t mid = {-0.7, 0.7, 0.0};
float scrparams[] = {0., 0., 5.0}; /* Max-Z, Minsize, Maxsize */
float texprops[] = {TX_MINFILTER,TX_MIPMAP_TRILINEAR,TX_MAGFILTER,TX_BILINEAR,
TX_WRAP,TX_REPEAT,TX_NULL};
float tevprops[] = {TV_COLOR,0.99,0.0,0.99,TV_MODULATE,TV_NULL};
float mat1[] = {
AMBIENT, .2, .2, .2,
DIFFUSE, 1, .1, .1,
SPECULAR, .7, .7, .7,
SHININESS, 30,
LMNULL };
float mat2[] = {
AMBIENT, .3, .3, .3,
DIFFUSE, .5, 1., .3,
SPECULAR, .5, .5, .5,
SHININESS, 10,
LMNULL };
static float lm[] = {
AMBIENT, .7, .7, .7,
LOCALVIEWER, 1,
LMNULL };
static float lt[] = {
LCOLOR, 1, 1, 1,
POSITION, 20., -10., 10., 0,
LMNULL };
/********************************************************************************/
void draw_tri(tri_t *tri)
{
point_t normal,vect12,vect13,v_axis;
float len,u_offset,v_offset,uv1[2],uv2[2],uv3[2];
Angle angle;
/* Define coordinate axes: +U is 1-->2 */
/* +V is orthogonal to +U and to normal */
uv1[U] = 0.0;
uv1[V] = 0.0;
uv2[V] = 0.0;
SUBXYZ(vect12,(*tri).v1.xyz,(*tri).v2.xyz); /* 1-->2 */
uv2[U] = XYZ_LEN(vect12); /* Length of 1-->2 is U for vertex 2 */
DIVXYZ(vect12,uv2[U]); /* Normalize vect12 */
uv3[U] = DOT(vect12,vect13); /* Projection of 3 on 1-->2 line */
SUBXYZ(vect13,(*tri).v1.xyz,(*tri).v3.xyz); /* 1-->3 */
CROSS3D(normal,vect12,vect13); /* Normal is orthogonal to 1-->2 and 1-->3 */
NORMALIZE(normal,len); /* Normal vector should be length 1 */
CROSS3D(v_axis,normal,vect12); /* V axis is ortho to normal and 1-->3 */
uv3[V] = DOT(vect13,v_axis); /* Projection of 3 on V axis */
u_offset = (float)rand() / (float)RAND_MAX;
v_offset = (float)rand() / (float)RAND_MAX;
uv1[U] += u_offset; /* Translate U,Vs by random vector */
uv1[V] += v_offset;
uv2[U] += u_offset;
uv2[V] += v_offset;
uv3[U] += u_offset;
uv3[V] += v_offset;
if (normal[Z] < 0.0) FLIP(normal);
if (texmap_random)
{
mmode(MTEXTURE);
angle = rand() / (RAND_MAX / 3600);
rotate(angle,'z');
mmode(MVIEWING);
}
bgnpolygon();
t2f(uv1); n3f(normal); v3f((*tri).v1.xyz);
t2f(uv2); n3f(normal); v3f((*tri).v2.xyz);
t2f(uv3); n3f(normal); v3f((*tri).v3.xyz);
endpolygon();
}
void make_mat3x3 (mat3x3_t *mat, p9_t *axis, float angle)
{
float radians,s,c,t,x,y,z;
/* Make matrix for rotation about arbitrary axis */
/* See Graphic Gems I, Page 466 */
radians = 2.0 * PI * angle / 360.;
if (angle >= 0.0)
s = sin(radians);
else
s = -sin(-radians);
c = cos(radians);
t = 1.0 - c;
x = (*axis).xyz[X];
y = (*axis).xyz[Y];
z = (*axis).xyz[Z];
(*mat)[X][X] = t * x * x + c;
(*mat)[X][Y] = t * x * y + s * z;
(*mat)[X][Z] = t * x * z - s * y;
(*mat)[Y][X] = t * x * y - s * z;
(*mat)[Y][Y] = t * y * y + c;
(*mat)[Y][Z] = t * y * z + s * x;
(*mat)[Z][X] = t * x * z + s * y;
(*mat)[Z][Y] = t * y * z - s * x;
(*mat)[Z][Z] = t * z * z + c;
}
void my_rotate (mat3x3_t *mat, p9_t *p, p9_t *center)
{
float new_x,new_y,new_z,new_nx,new_ny,new_nz;
/* Rotate point "p" around center point "center" using rotation matrix "mat" */
(*p).xyz[X] -= (*center).xyz[X];
(*p).xyz[Y] -= (*center).xyz[Y];
(*p).xyz[Z] -= (*center).xyz[Z];
new_x = (*p).xyz[X] * (*mat)[X][X] + (*p).xyz[Y] * (*mat)[X][Y] + (*p).xyz[Z] * (*mat)[X][Z];
new_y = (*p).xyz[X] * (*mat)[Y][X] + (*p).xyz[Y] * (*mat)[Y][Y] + (*p).xyz[Z] * (*mat)[Y][Z];
new_z = (*p).xyz[X] * (*mat)[Z][X] + (*p).xyz[Y] * (*mat)[Z][Y] + (*p).xyz[Z] * (*mat)[Z][Z];
new_nx = (*p).n[X] * (*mat)[X][X] + (*p).n[Y] * (*mat)[X][Y] + (*p).n[Z] * (*mat)[X][Z];
new_ny = (*p).n[X] * (*mat)[Y][X] + (*p).n[Y] * (*mat)[Y][Y] + (*p).n[Z] * (*mat)[Y][Z];
new_nz = (*p).n[X] * (*mat)[Z][X] + (*p).n[Y] * (*mat)[Z][Y] + (*p).n[Z] * (*mat)[Z][Z];
(*p).xyz[X] = new_x + (*center).xyz[X];
(*p).xyz[Y] = new_y + (*center).xyz[Y];
(*p).xyz[Z] = new_z + (*center).xyz[Z];
(*p).n[X] = new_nx;
(*p).n[Y] = new_ny;
(*p).n[Z] = new_nz;
}
void pos_and_draw(mat3x3_t *, p9_t *, p9_t *, p9_t *, p9_t *);
void draw_twiz(long count, float twists)
{
mat3x3_t mat;
p9_t p1,p2,p3,p4,cp,ra,old_p1,old_p2,old_p3,old_p4;
float x_angle_step,ra_angle_step;
float across,dist_1,dist_2,dist_3,dist_4,avg_step;
long i;
/* "Twiz" is a square-crosssection torus with a twist */
SETXYZ(p1.xyz, -0.5, 0.5, 0.0); /* p1 - p4 are corners of square cross-section */
SETXYZ(p2.xyz, -0.5, 0.9, 0.0);
SETXYZ(p3.xyz, -0.9, 0.9, 0.0);
SETXYZ(p4.xyz, -0.9, 0.5, 0.0);
SETXYZ(p1.n, 1.0, 0.0, 0.0);
SETXYZ(p2.n, 0.0, 1.0, 0.0);
SETXYZ(p3.n, -1.0, 0.0, 0.0);
SETXYZ(p4.n, 0.0,-1.0, 0.0);
SETXYZ(cp.xyz, -0.7, 0.7, 0.0); /* cp is center of square...for its rotation */
SETXYZ(ra.xyz, 0.0, 0.0, 1.0); /* ra is rotation axis...normal to square */
SET2(p1.t, 1.0, 0.0); /* Bottom right */
SET2(p2.t, 0.0, 0.0); /* Bottom left */
SET2(p3.t, 1.0, 0.0); /* Bottom right */
SET2(p4.t, 0.0, 0.0); /* Bottom left */
x_angle_step = 360.0 / (float)count; /* Degrees per step around torus */
ra_angle_step = twists * x_angle_step; /* Degrees per step to twist cross-section */
across = ABS(p3.xyz[X] - p1.xyz[X]); /* Across square */
lmbind(MATERIAL, 1);
texbind(TX_TEXTURE_0,1);
for (i=0; i<count; i++)
{
memcpy(&old_p1,&p1,sizeof(p9_t)); /* Save corners and normals */
memcpy(&old_p2,&p2,sizeof(p9_t));
memcpy(&old_p3,&p3,sizeof(p9_t));
memcpy(&old_p4,&p4,sizeof(p9_t));
make_mat3x3(&mat,&ra,(float)ra_angle_step); /* Twist rotation */
my_rotate(&mat,&p1,&cp); /* Twist the square around cp by ra_angle_step */
my_rotate(&mat,&p2,&cp);
my_rotate(&mat,&p3,&cp);
my_rotate(&mat,&p4,&cp);
make_mat3x3(&mat,&xa,x_angle_step); /* Around-the-torus rotation */
my_rotate(&mat,&p1,&org); /* Sweep p1-p4 and cp around torus */
my_rotate(&mat,&p2,&org);
my_rotate(&mat,&p3,&org);
my_rotate(&mat,&p4,&org);
my_rotate(&mat,&cp,&org);
my_rotate(&mat,&ra,&org); /* Rotate ra around torus also */
dist_1 = DISTANCE(p1.xyz,old_p1.xyz);
dist_2 = DISTANCE(p2.xyz,old_p2.xyz);
dist_3 = DISTANCE(p3.xyz,old_p3.xyz);
dist_4 = DISTANCE(p4.xyz,old_p4.xyz);
avg_step = AVG4F(dist_1,dist_2,dist_3,dist_4) / across;
p1.t[Y] += avg_step; /* Advance texture Y */
p2.t[Y] += avg_step;
p3.t[Y] += avg_step;
p4.t[Y] += avg_step;
make_mat3x3(&mat,&za,10.0); /* Rotate 10 degrees around Z to position in scene */
pos_and_draw(&mat,&p1,&p2,&old_p2,&old_p1); /* Draw slightly twisted quads for twiz sides */
pos_and_draw(&mat,&p2,&p3,&old_p3,&old_p2);
pos_and_draw(&mat,&p3,&p4,&old_p4,&old_p3);
pos_and_draw(&mat,&p4,&p1,&old_p1,&old_p4);
}
texbind(TX_TEXTURE_0,0);
}
void draw_quad_n(p9_t *, p9_t *, p9_t *, p9_t *);
void pos_and_draw(mat3x3_t *mat, p9_t *pa, p9_t *pb, p9_t *pc, p9_t *pd)
{
p9_t pa_copy,pb_copy,pc_copy,pd_copy;
memcpy(&pa_copy,pa,sizeof(p9_t));
memcpy(&pb_copy,pb,sizeof(p9_t));
memcpy(&pc_copy,pc,sizeof(p9_t));
memcpy(&pd_copy,pd,sizeof(p9_t));
my_rotate(mat,&pa_copy,&mid);
my_rotate(mat,&pb_copy,&mid);
my_rotate(mat,&pc_copy,&mid);
my_rotate(mat,&pd_copy,&mid);
draw_quad_n(&pa_copy,&pb_copy,&pc_copy,&pd_copy);
}
void draw_quad_n(p9_t *pa, p9_t *pb, p9_t *pc, p9_t *pd)
{
float array[3];
Angle angle;
if (texmap_random)
{
mmode(MTEXTURE);
angle = rand() / (RAND_MAX / 3600);
rotate(angle,'z');
mmode(MVIEWING);
}
bgnpolygon();
t2f((*pa).t);
n3f((*pa).n);
v3f((*pa).xyz);
t2f((*pb).t);
n3f((*pa).n);
v3f((*pb).xyz);
t2f((*pc).t);
n3f((*pd).n);
v3f((*pc).xyz);
t2f((*pd).t);
n3f((*pd).n);
v3f((*pd).xyz);
endpolygon();
}
void output_point(p9_t *p, long how)
{
float array3[3];
float array2[2];
if (how & USE_NORMAL) n3f( (*p).n);
if (how & USE_COLOR) cpack((*p).abgr);
if (how & USE_TEXTURE) t2f( (*p).t);
v3f((*p).xyz);
}
void draw_quad(p9_t *pa, p9_t *pb, p9_t *pc, p9_t *pd, long how)
{
Angle angle;
/* Draw a polygon, using "how" as bit-vector of options */
if (texmap_random)
{
mmode(MTEXTURE);
angle = rand() / (RAND_MAX / 3600);
rotate(angle,'z');
mmode(MVIEWING);
}
bgnpolygon();
output_point(pa,how);
output_point(pb,how);
output_point(pc,how);
output_point(pd,how);
endpolygon();
}
void draw_floor(long count)
{
long i,k;
float istep,kstep;
p9_t p1,p2,p3,p4;
/* Repeat pattern count x 4*count times on a horizontal plane */
texbind(TX_TEXTURE_0,1);
tevbind(TV_ENV0,1);
cpack(0xffffffff); /* Multiply this color! */
p1.xyz[Z] = p2.xyz[Z] = p3.xyz[Z] = p4.xyz[Z] = -0.5;
istep = 4.0 / (float)count;
kstep = 4.0 / (float)count;
p1.t[0] = 0.0;
p1.t[1] = 0.0;
p2.t[0] = 1.0;
p2.t[1] = 0.0;
p3.t[0] = 1.0;
p3.t[1] = 1.0;
p4.t[0] = 0.0;
p4.t[1] = 1.0;
for (i=0; i<count; i++)
for (k=0; k<4*count; k++)
{
p1.xyz[X] = -2.0 + istep * (float) i;
p1.xyz[Y] = -2.0 + kstep * (float) k;
p2.xyz[X] = -2.0 + istep * (float) (i+1);
p2.xyz[Y] = -2.0 + kstep * (float) k;
p3.xyz[X] = -2.0 + istep * (float) (i+1);
p3.xyz[Y] = -2.0 + kstep * (float) (k+1);
p4.xyz[X] = -2.0 + istep * (float) i;
p4.xyz[Y] = -2.0 + kstep * (float) (k+1);
if ((i & 1) == (k & 1))
p1.abgr = p2.abgr = p3.abgr = p4.abgr = 0;
else
p1.abgr = p2.abgr = p3.abgr = p4.abgr = 0xffffff;
draw_quad(&p1,&p2,&p3,&p4,USE_TEXTURE);
}
texbind(TX_TEXTURE_0,0);
}
float pseudorandom(p9_t *end1, p9_t *end2, long seed)
{
long *long_ptr,xor,x1,y1,z1,x2,y2,z2,base;
float frac;
if (seed >= 156) seed = 0;
base = primes[seed++];
long_ptr = (long *)end1->xyz;
x1 = *long_ptr++;
y1 = *long_ptr++;
z1 = *long_ptr++;
long_ptr = (long *)end2->xyz;
x2 = *long_ptr++;
y2 = *long_ptr++;
z2 = *long_ptr++;
xor = x1 ^ y1 ^ z1 ^ x2 ^ y2 ^ z2;
frac = (float)ABS(xor % base) / (float)(base-1);
return(frac);
}
void perturb(p9_t *end1, p9_t *end2, p9_t *mid)
{
float frac,len,min;
min = (1.0 - my_noise) / 2.0;
frac = min + my_noise * pseudorandom(end1,end2,seed);
(*mid).xyz[X] = frac * (*end1).xyz[X] + (1.0 - frac) * (*end2).xyz[X];
(*mid).t[0] = frac * (*end1).t[0] + (1.0 - frac) * (*end2).t[0];
frac = min + my_noise * pseudorandom(end1,end2,seed+1);
(*mid).xyz[Y] = frac * (*end1).xyz[Y] + (1.0 - frac) * (*end2).xyz[Y];
(*mid).t[1] = frac * (*end1).t[1] + (1.0 - frac) * (*end2).t[1];
frac = min + my_noise * pseudorandom(end1,end2,seed);
(*mid).xyz[Z] = frac * (*end1).xyz[Z] + (1.0 - frac) * (*end2).xyz[Z];
len = DISTANCE((*end1).xyz,(*end2).xyz);
(*mid).xyz[Z] += my_noise * sqrtf(len) * pseudorandom(end1,end2,seed+3);
}
void subdivide_triangle(tri_t *parent, long level)
{
tri_t child;
tri_tex_t tri_tex;
p9_t mid12,mid13,mid23;
/* parent is the address of tri in build_mountain */
/* Recursively subdivide triangle to make fractal mountain */
if (level == 0) /* Stop recursion? */
{
draw_tri(parent); /* Draw it, don't subdivide it further */
return;
}
/* Connect side midpoints to make four children */
perturb(&parent->v1,&parent->v2,&mid12);
perturb(&parent->v1,&parent->v3,&mid13);
perturb(&parent->v2,&parent->v3,&mid23);
memcpy(&child.v1,&parent->v1,sizeof(p9_t));
memcpy(&child.v2,&mid12,sizeof(p9_t));
memcpy(&child.v3,&mid13,sizeof(p9_t));
subdivide_triangle(&child,level-1);
memcpy(&child.v1,&parent->v2,sizeof(p9_t));
memcpy(&child.v2,&mid12,sizeof(p9_t));
memcpy(&child.v3,&mid23,sizeof(p9_t));
subdivide_triangle(&child,level-1);
memcpy(&child.v1,&parent->v3,sizeof(p9_t));
memcpy(&child.v2,&mid13,sizeof(p9_t));
memcpy(&child.v3,&mid23,sizeof(p9_t));
subdivide_triangle(&child,level-1);
memcpy(&child.v1,&mid12,sizeof(p9_t));
memcpy(&child.v2,&mid13,sizeof(p9_t));
memcpy(&child.v3,&mid23,sizeof(p9_t));
subdivide_triangle(&child,level-1);
}
void build_mountain(long detail)
{
tri_t tri;
texbind(TX_TEXTURE_0,1);
lmbind(MATERIAL, 2);
SETXYZ(tri.v1.xyz,-15.0,14.0,-8.0); /* Initial large, wide, tilted triangle */
SETXYZ(tri.v2.xyz, 15.0,14.0,-8.0);
SETXYZ(tri.v3.xyz, 0.0,20.0,10.0);
SET2(tri.v1.t,-1.5,-0.4);
SET2(tri.v2.t, 1.5,-0.4);
SET2(tri.v3.t, 0.0, 1.4);
subdivide_triangle(&tri,detail);
texbind(TX_TEXTURE_0,0);
}
unsigned long *format_texture(image_t *im)
{
long x,y,rgb;
unsigned long *wptr,*texture;
char *bptr;
long *iptr;
alpha_t *aptr;
texture_width = im->interior_xsize;
texture_height = im->interior_ysize;
texture_components_per_pixel = 3;
if (im->whole_alpha_org != NULL) texture_components_per_pixel = 4;
texture = (unsigned long *)calloc(im->interior_xsize * im->interior_ysize,
texture_components_per_pixel);
wptr = texture; /* For ABGR format */
bptr = (char *)texture; /* In case we go byte by byte (BGR) */
iptr = im->interior_org; /* Destination: lrectread format */
aptr = im->interior_alpha_org; /* Source: alpha as array of char */
for (y=0; y<im->interior_ysize; y++)
{
if (texture_components_per_pixel == 3)
for (x=0; x<im->interior_xsize; x++)
{
*bptr++ = CLAMP511 (EXTRACT_BLU(*iptr)) >> 1;
*bptr++ = CLAMP1023(EXTRACT_GRN(*iptr)) >> 2;
*bptr++ = CLAMP1023(EXTRACT_RED(*iptr)) >> 2;
iptr++;
}
else if (texture_components_per_pixel == 4)
for (x=0; x<im->interior_xsize; x++)
{
rgb = *iptr++;
*wptr++ = LARGE_TO_888(rgb) | *aptr++ << 24;
}
iptr += im->pixels_interior_wrap;
}
return(texture);
}
void draw_texture_scene(long j)
{
long count,fractalaciousness,floor_repeats;
float twists;
/* if (!getgdesc(GD_TEXTURE)) return; */
mmode(MVIEWING);
pushmatrix();
perspective(700,1.0,0.1,50.0); /* 70 degree view, 1:1, near = .1, far = 50 */
polarview(2.6,0,900,0);
zbuffer(TRUE);
subpixel(TRUE);
if (!texture_loaded)
{
texdef2d(1,texture_components_per_pixel,texture_width,texture_height,
texture_image_in_mem,0,texprops);
tevdef(1,0,tevprops);
scrsubdivide(SS_DEPTH,scrparams);
lmdef(DEFMATERIAL, 1, 0, mat1);
lmdef(DEFMATERIAL, 2, 0, mat2);
lmdef(DEFLIGHT, 1, 0, lt);
lmdef(DEFLMODEL, 1, 0, lm);
lmbind(LMODEL, 1);
lmbind(LIGHT0, 1);
maximum_z = getgdesc(GD_ZMAX);
texture_loaded = TRUE;
}
czclear(IBC,maximum_z);
count = 50;
twists = 0.25;
floor_repeats = 10;
fractalaciousness = 7;
my_noise = 0.8;
seed = 0;
/*
mmode(MTEXTURE);
loadmatrix(identity);
*/
mmode(MVIEWING);
draw_floor(floor_repeats);
build_mountain(fractalaciousness);
draw_twiz(count,twists);
mmode(MVIEWING);
ortho2(0,851,0,551);
popmatrix();
zbuffer(FALSE);
subpixel(FALSE);
redisplay_all_widgets();
}
void show_buttons(long j)
{
long k,l;
if (show_indexes[0] == j)
{
if (ipt[j].data == 1) return;
ipt[j].data = 1;
ipt[j].redisplay_ui_proc(j);
k = show_indexes[1];
if (ipt[j].data == 1 && ipt[k].data == 1)
{
ipt[k].data = 0;
ipt[k].redisplay_ui_proc(k);
}
texmap_random = ipt[j].data;
draw_texture_scene(0);
}
else if (show_indexes[1] == j)
{
if (ipt[j].data == 1) return;
ipt[j].data = 1;
ipt[j].redisplay_ui_proc(j);
k = show_indexes[0];
if (ipt[j].data == 1 && ipt[k].data == 1)
{
ipt[k].data = 0;
ipt[k].redisplay_ui_proc(k);
}
texmap_random = ipt[j].data;
draw_texture_scene(0);
}
else if (show_indexes[2] == j)
{
if (ipt[j].data == 1) return;
ipt[j].data = 1;
ipt[j].redisplay_ui_proc(j);
k = show_indexes[3];
l = show_indexes[4];
if (ipt[j].data == 1 && ipt[k].data == 1)
{
ipt[k].data = 0;
ipt[k].redisplay_ui_proc(k);
}
if (ipt[j].data == 1 && ipt[l].data == 1)
{
ipt[l].data = 0;
ipt[l].redisplay_ui_proc(l);
}
tex_prop_select = TX_POINT;
texprops[1] = TX_POINT;
texprops[3] = TX_POINT;
texdef2d(1,texture_components_per_pixel,texture_width,texture_height,
texture_image_in_mem,0,texprops);
draw_texture_scene(0);
}
else if (show_indexes[3] == j)
{
if (ipt[j].data == 1) return;
ipt[j].data = 1;
ipt[j].redisplay_ui_proc(j);
k = show_indexes[2];
l = show_indexes[4];
if (ipt[j].data == 1 && ipt[k].data == 1)
{
ipt[k].data = 0;
ipt[k].redisplay_ui_proc(k);
}
if (ipt[j].data == 1 && ipt[l].data == 1)
{
ipt[l].data = 0;
ipt[l].redisplay_ui_proc(l);
}
tex_prop_select = TX_BILINEAR;
texprops[1] = TX_BILINEAR;
texprops[3] = TX_BILINEAR;
texdef2d(1,texture_components_per_pixel,texture_width,texture_height,
texture_image_in_mem,0,texprops);
draw_texture_scene(0);
}
else if (show_indexes[4] == j)
{
if (ipt[j].data == 1) return;
ipt[j].data = 1;
ipt[j].redisplay_ui_proc(j);
k = show_indexes[2];
l = show_indexes[3];
if (ipt[j].data == 1 && ipt[k].data == 1)
{
ipt[k].data = 0;
ipt[k].redisplay_ui_proc(k);
}
if (ipt[j].data == 1 && ipt[l].data == 1)
{
ipt[l].data = 0;
ipt[l].redisplay_ui_proc(l);
}
tex_prop_select = TX_MIPMAP_TRILINEAR;
texprops[1] = TX_MIPMAP_TRILINEAR;
texprops[3] = TX_BILINEAR;
texdef2d(1,texture_components_per_pixel,texture_width,texture_height,
texture_image_in_mem,0,texprops);
draw_texture_scene(0);
}
else if (show_indexes[5] == j)
{
map_rotation += 90;
if (map_rotation > 270) map_rotation = 0;
mmode(MTEXTURE);
rotate(900,'z');
mmode(MVIEWING);
draw_texture_scene(0);
}
else
{
printf("Show_button called with j = %d\n",j);
exit(15);
}
}
void cleanup_show()
{
turn_off_all_widgets();
}
void reveal_coord(char *text, float x, float y, long color)
{
char mess[100];
sprintf(mess,"%5.2f,%5.2f,0.0 %s",x,y,text);
cpack(color);
cmov(x,y,0.0);
charstr(mess);
sginap(100);
}